package com.gsafety.wellsfort.controller.verifyCode;

import com.alibaba.fastjson.JSONObject;
import com.gsafety.wellsfort.annotation.CheckToken;
import com.gsafety.wellsfort.common.enums.RedisPrefixEnum;
import com.gsafety.wellsfort.common.util.ApiResponse;
import com.gsafety.wellsfort.common.util.ResultCode;
import com.gsafety.wellsfort.common.util.StringHelper;
import com.gsafety.wellsfort.config.CacheManager;
import com.gsafety.wellsfort.domain.model.security.Admin;
import com.gsafety.wellsfort.domain.model.security.UserLogin;
import com.gsafety.wellsfort.domain.vo.CheckSmsVO;
import com.gsafety.wellsfort.domain.vo.SmsVO;
import com.gsafety.wellsfort.service.common.SmsService;
import com.gsafety.wellsfort.service.security.IAdminService;
import com.gsafety.wellsfort.service.security.IUserLoginService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Api(description = "获取验证码接口")
@RestController
@Slf4j
@RequestMapping("/api/verifyCode")
public class VerifyCodeController {

    @Autowired
    private CacheManager cacheManager;

    @Autowired
    private SmsService smsService;

    @Autowired
    private IUserLoginService userLoginService;

    @Autowired
    private IAdminService adminService;

    /**
     * 手机白名单
     */
    public static final List<String> phoneList = Arrays.asList("17610920058", "15620970743","13252577671","13699209509","18810594763");

    @ApiOperation(value = "获取图形验证码")
    @CheckToken(value = false)
    @PostMapping("/get")
    public ApiResponse get() {
        //验证码校验
        JSONObject jsonObject = new JSONObject();
        String token = StringHelper.generateRandomCode(15);
        String code = StringHelper.getRandomDigitString(4);
        cacheManager.set(token, code, 5 * 60);
        jsonObject.put("token", token);
        jsonObject.put("code", code);
        return ApiResponse.success(jsonObject);
    }

    /**
     * 短信验证码限制:单个手机号60秒不能再次发送  每天6次 暂定这个规格就好
     *
     * @param smsVO
     * @return
     */
    @ApiOperation(value = "获取短信验证码")
    @CheckToken(value = false)
    @PostMapping("/getSms")
    public ApiResponse getSms(@RequestBody SmsVO smsVO) {
        if (smsVO.getType() != null && smsVO.getType() == 2) {
            //管理员忘记密码特殊处理,传递账号转换成手机号
            UserLogin userLogin = userLoginService.getUserLoginByAccount(smsVO.getPhone());
            if (userLogin == null) {
                return ApiResponse.error(ResultCode.INVALID_PARAM);
            }
            Admin admin = adminService.getByLoginId(userLogin.getId());
            smsVO.setPhone(admin.getPhone());
        }
        if (StringUtils.isNotEmpty(cacheManager.get(RedisPrefixEnum.SMS_CAPTCHA_PREFIX.getPrefix() + smsVO.getPhone()))) {
            return ApiResponse.error(ResultCode.ERROR.MESSAGE_CODE_FREQUENTLY);
        }
        //手机号验证:单天,一个手机号最多只能发送6次
        String count = cacheManager.get(RedisPrefixEnum.PHONE_SEND_COUNT_PREFIX.getPrefix() + smsVO.getPhone());
        if (count == null) {
            cacheManager.set(RedisPrefixEnum.PHONE_SEND_COUNT_PREFIX.getPrefix() + smsVO.getPhone(), new String("1"), RedisPrefixEnum.PHONE_SEND_COUNT_PREFIX.getExpireTime());
        } else {
            if (Integer.parseInt(count) > 6 && !phoneList.contains(smsVO.getPhone())) {
                return ApiResponse.error(ResultCode.REQUEST_SMS_SERVICE_COUNT_ERROR);
            }
            cacheManager.set(RedisPrefixEnum.PHONE_SEND_COUNT_PREFIX.getPrefix() + smsVO.getPhone(), String.valueOf(Integer.parseInt(count) + 1), RedisPrefixEnum.PHONE_SEND_COUNT_PREFIX.getExpireTime());
        }
        if (smsVO.getType() != null && smsVO.getType() == 1) {
            //注册验证码,需要验证该手机号是否已经注册
            UserLogin userLogin = userLoginService.getUserLoginByAccount(smsVO.getPhone());
            if (userLogin != null) {
                return ApiResponse.error(ResultCode.PHONE_IS_EXIST);
            }
        }
        if (smsService.sendCaptcha(smsVO.getPhone(), RedisPrefixEnum.SMS_CAPTCHA_PREFIX)) {
            return ApiResponse.success();
        } else {
            return ApiResponse.error();
        }
    }

    /**
     * @param checkSmsVO
     * @return
     */
    @ApiOperation(value = "校验验证码")
    @CheckToken(value = false)
    @PostMapping("/checkSms")
    public ApiResponse checkSms(@RequestBody CheckSmsVO checkSmsVO) {
        String captcha = cacheManager.get(RedisPrefixEnum.SMS_CAPTCHA_PREFIX.getPrefix() + checkSmsVO.getPhone());
        if (StringUtils.isEmpty(captcha) || !Objects.equals(captcha, checkSmsVO.getCaptcha())) {
            return ApiResponse.error(ResultCode.CAPTCHA_ERROR);
        }
        return ApiResponse.success();
    }

    /**
     * @param checkSmsVO
     * @return
     */
    @ApiOperation(value = "校验验证码")
    @CheckToken(value = false)
    @PostMapping("/checkSmsByAccount")
    public ApiResponse checkSmsByAccount(@RequestBody CheckSmsVO checkSmsVO) {
        String phone = null;
        UserLogin userLogin = userLoginService.getUserLoginByAccount(checkSmsVO.getAccount());
        if (userLogin == null) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        Admin admin = adminService.getByLoginId(userLogin.getId());
        if (admin == null) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        phone = admin.getPhone();
        String smsCode = cacheManager.get(RedisPrefixEnum.SMS_CAPTCHA_PREFIX.getPrefix() + phone);
        if (StringUtils.isEmpty(smsCode) || !smsCode.equalsIgnoreCase(checkSmsVO.getCaptcha())) {
            return ApiResponse.error(ResultCode.CAPTCHA_ERROR);
        }
        return ApiResponse.success();
    }

    /**
     * @param checkSmsVO
     * @return
     */
    @ApiOperation(value = "校验验证码")
    @CheckToken(value = false)
    @PostMapping("/checkCaptcha")
    public ApiResponse checkCaptcha(@RequestBody CheckSmsVO checkSmsVO) {
        //后台登录使用图形验证码登录,必须要传递token
        String captcha = cacheManager.get(checkSmsVO.getToken());
        if (StringUtils.isEmpty(captcha) || !captcha.equalsIgnoreCase(checkSmsVO.getCaptcha())) {
            return ApiResponse.error(ResultCode.IMG_CAPTCHA_IS_ERROR);
        }
        return ApiResponse.success();
    }
}
